package com.loong.common.rabbitmq.configuration;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.loong.common.rabbitmq.producer.CustomCallback;
import org.springframework.amqp.rabbit.batch.BatchingStrategy;
import org.springframework.amqp.rabbit.batch.SimpleBatchingStrategy;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.BatchingRabbitTemplate;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

import javax.annotation.Resource;

@Configuration("rabbitmqDefaultConfiguration")
@DependsOn(value = {"rabbitmqConnectionFactoryConfiguration"})
public class DefaultConfiguration {

    @Resource
    private CustomCallback customCallback;

    @Bean(name = "defaultRabbitAdmin")
    public RabbitAdmin defaultRabbitAdmin(@Qualifier("defaultConnectionFactory") ConnectionFactory connectionFactory) {
        RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
        return rabbitAdmin;
    }

    @Bean(name = "defaultRabbitTemplate")
    public RabbitTemplate defaultRabbitTemplate(@Qualifier("defaultConnectionFactory") ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter(mapper));
        rabbitTemplate.setMandatory(true);
        rabbitTemplate.setEncoding("UTF-8");
        rabbitTemplate.setReturnCallback(customCallback);
        rabbitTemplate.setConfirmCallback(customCallback);
        return rabbitTemplate;
    }

    @Bean(name = "defaultRabbitListener")
    public SimpleRabbitListenerContainerFactory defaultRabbitListener(
            SimpleRabbitListenerContainerFactoryConfigurer configurer,
            @Value("${loong.slave.customer.prefetch.size}") Integer prefetchSize,
            @Qualifier("defaultConnectionFactory") ConnectionFactory connectionFactory) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setPrefetchCount(prefetchSize);
        configurer.configure(factory, connectionFactory);
        return factory;
    }

//    /**
//     *
//     * 批量监听
//     * @param connectionFactory
//     * @return
//     */
//    @Bean("batchQueueRabbitListenerContainerFactory")
//    public SimpleRabbitListenerContainerFactory batchQueueRabbitListenerContainerFactory(@Qualifier("defaultConnectionFactory")ConnectionFactory connectionFactory) {
//        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
//        factory.setConnectionFactory(connectionFactory);
//        //设置批量
//        factory.setBatchListener(true);
//        factory.setConsumerBatchEnabled(true);//设置BatchMessageListener生效
//        factory.setBatchSize(5);//设置监听器一次批量处理的消息数量
//        return factory;
//    }
//
//    @Bean("batchQueueTaskScheduler")
//    public TaskScheduler batchQueueTaskScheduler(){
//        TaskScheduler taskScheduler=new ThreadPoolTaskScheduler();
//        return taskScheduler;
//    }
//    //批量处理rabbitTemplate
//    @Bean("batchQueueRabbitTemplate")
//    public BatchingRabbitTemplate batchQueueRabbitTemplate(@Qualifier("defaultConnectionFactory")ConnectionFactory connectionFactory,
//                                                           @Qualifier("batchQueueTaskScheduler") TaskScheduler taskScheduler){
//
//        // 所谓批量， 就是spring 将多条message重新组成一条message, 发送到mq, 从mq接受到这条message后，在重新解析成多条message
//        //一次批量的数量
//        int batchSize=5;
//        // 缓存大小限制,单位字节，
//        // simpleBatchingStrategy的策略，是判断message数量是否超过batchSize限制或者message的大小是否超过缓存限制，
//        // 缓存限制，主要用于限制"组装后的一条消息的大小"
//        // 如果主要通过数量来做批量("打包"成一条消息), 缓存设置大点
//        // 详细逻辑请看simpleBatchingStrategy#addToBatch()
//        int bufferLimit=1024; //1 K
//        long timeout=10000;
//
//        //注意，该策略只支持一个exchange/routingKey
//        //A simple batching strategy that supports only one exchange/routingKey
//        BatchingStrategy batchingStrategy=new SimpleBatchingStrategy(batchSize,bufferLimit,timeout);
//        return new BatchingRabbitTemplate(connectionFactory,batchingStrategy,taskScheduler);
//    }
}
